package cn.itsource.ymcc.service.impl;

import cn.itsource.ymcc.constant.RConst;
import cn.itsource.ymcc.domain.*;
import cn.itsource.ymcc.mapper.*;
import cn.itsource.ymcc.openfeign.MediaOpenfeign;
import cn.itsource.ymcc.openfeign.SearchCourseOpenfeign;
import cn.itsource.ymcc.producer.CourseMessageProducer;
import cn.itsource.ymcc.result.JsonResult;
import cn.itsource.ymcc.service.ICourseService;
import cn.itsource.ymcc.service.ITeacherService;
import cn.itsource.ymcc.util.AssertUtil;
import cn.itsource.ymcc.vo.CourseVo;
import cn.itsource.ymcc.vo.OnlineCourseVo;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import springfox.documentation.spring.web.json.Json;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zongchangjiang
 * @since 2023-06-26
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {
    @Autowired
    private CourseDetailMapper courseDetailMapper;
    @Autowired
    private CourseMarketMapper courseMarketMapper;
    @Autowired
    private CourseResourceMapper courseResourceMapper;
    @Autowired
    private CourseSummaryMapper courseSummaryMapper;
    @Autowired
    private ITeacherService teacherService;
    @Autowired
    private SearchCourseOpenfeign searchCourseOpenfeign;
    @Autowired
    private CourseTypeMapper courseTypeMapper;
    @Autowired
    private CourseCollectMapper courseCollectMapper;
    @Autowired
    private CourseMessageProducer courseMessageProducer;
    @Autowired
    private CourseChapterMapper courseChapterMapper;
    @Autowired
    private MediaOpenfeign mediaOpenfeign;


    @Override
    public boolean updateById(CourseVo entity) {
        return false;
    }

    // teacherService.list(new LambdaQueryWrapper<Teacher>().in(Teacher::getId,teacharIds));
    @Transactional
    @Override
    public boolean save(CourseVo entity,String username,Long id) {
        Course course = entity.getCourse();//获取 课程信息

        List<Long> teacharIds = entity.getTeacharIds();//得到老师的id
        List<Teacher> teachers = teacherService.list(new QueryWrapper<Teacher>() //根据老师的id去查询老师
                .in(teacharIds.size() > 0, "id", teacharIds));
        List<String> collect = teachers.stream().map(Teacher::getName).collect(Collectors.toList());//将List里面的老师的name取出来
        String names = String.join(",", collect);//使用,做拼接
        course.setTeacherNames(names);
        //设置默认值
        course.setStatus(RConst.Num.INT_0);
        course.setLoginId(id);
        course.setLoginUserName(username);
        baseMapper.insert(course);// 会自动将主键id返回给对象

        //课程详情数据
        CourseDetail courseDetail = entity.getCourseDetail();
        courseDetail.setId(course.getId());
        courseDetailMapper.insert(courseDetail);

        //课程 销售价格相关的
        CourseMarket courseMarket = entity.getCourseMarket();
        courseMarket.setId(course.getId());
        courseMarketMapper.insert(courseMarket);

        //课程资源
        CourseResource courseResource = entity.getCourseResource();
        courseResource.setCourseId(course.getId());
        courseResourceMapper.insert(courseResource);

        //课程信息记录 销量 浏览器 评论数
        CourseSummary courseSummary = new CourseSummary();
        courseSummary.setId(course.getId());
        courseSummary.setCommentCount(RConst.Num.INT_0);
        courseSummary.setSaleCount(RConst.Num.INT_0);
        courseSummary.setViewCount(RConst.Num.INT_0);
        courseSummaryMapper.insert(courseSummary);

        //保存  课程和老师的关系
        baseMapper.saveCourseAndTeacher(course.getId(),teacharIds);
        return false;
    }

    /**
     * 根据  课程id 查询全部详情
     * @param id
     * @return
     */
    @Override
    public JsonResult getAllDetail(Long id) {
        CourseVo courseVo = new CourseVo();
        Course course = baseMapper.selectOne(new LambdaQueryWrapper<Course>().eq(Course::getId, id));
        courseVo.setCourse(course);
        if(course != null){
            CourseDetail courseDetail = courseDetailMapper.selectOne(new LambdaQueryWrapper<CourseDetail>().eq(CourseDetail::getId, id));
            courseVo.setCourseDetail(courseDetail);

            CourseMarket courseMarket = courseMarketMapper.selectOne(new LambdaQueryWrapper<CourseMarket>().eq(CourseMarket::getId, id));
            courseVo.setCourseMarket(courseMarket);

            CourseResource courseResource = courseResourceMapper.selectOne(new LambdaQueryWrapper<CourseResource>().eq(CourseResource::getCourseId, id));
            courseVo.setCourseResource(courseResource);

            List<Long> longs = baseMapper.selectTeacherIdByCourseId(id);
            courseVo.setTeacharIds(longs);
        }
        return JsonResult.success().setData(courseVo);
    }

    /**
     * 课程上线的操作
     * @param onlineCourseVo
     */
    @Transactional
    @Override
    public JsonResult onLineCourse(OnlineCourseVo onlineCourseVo) {
        //判断数据是否有值
        List<Long> ids = onlineCourseVo.getIds();
        //修改数据库状态
        updateOnLineStatus(ids);
        //将数据同步到es中
        synchronizeDataToES(ids);
        // 补偿 延迟消息  去查es 看数据是否存在
        return JsonResult.success();
    }

    /**
     * 经过你们的分析  数据在es中存在
     *    查询数据库
     *    查询es     效率更高
     * 我们的目的就是 练习openfeign
     * @param courseId
     * @return
     */
    @Override
    public JsonResult detailData(Long courseId) {
        Map<String,Object> map = new HashMap<>();//不够好
        JsonResult jsonResult = searchCourseOpenfeign.queryCourseDoc(courseId);
        CourseDoc courseDoc = JSON.parseObject(jsonResult.getData().toString(), CourseDoc.class);
        System.out.println(courseDoc);

        //封装数据
        Course course = new Course();
        BeanUtils.copyProperties(courseDoc,course);
        CourseMarket courseMarket = new CourseMarket();
        BeanUtils.copyProperties(courseDoc,courseMarket);

        CourseSummary courseSummary = new CourseSummary();
        BeanUtils.copyProperties(courseDoc,courseSummary);
        CourseDetail courseDetail = new CourseDetail();
        BeanUtils.copyProperties(courseDoc,courseDetail);
        //找老师
        List<Long> longs = baseMapper.selectTeacherIdByCourseId(courseId);
        List<Teacher> teachers = null;
        if(!longs.isEmpty()){
            teachers = teacherService.listByIds(longs);
        }

        //找课程章节
        //        BeanUtils.copyProperties(courseDoc,courseChapter);//我们支持es中去找  但是es没有
        List<CourseChapter> courseChapterList = courseChapterMapper.selectList(new QueryWrapper<CourseChapter>()
                .eq("course_id", courseId));
        if(!courseChapterList.isEmpty()){
            JsonResult mediaByCourseid = mediaOpenfeign.getMediaByCourseid(courseId);
            List<MediaFile> fileList = JSON.parseArray(mediaByCourseid.getData().toString(), MediaFile.class);
            //我一个的课程  下面有多个章节   多个章节下面有多个视频
            courseChapterList.forEach(courseChapter -> {
                //找到对应自己的视频 放进去就可以了
                List<MediaFile> mediaFiles = courseChapter.getMediaFiles();
                for (MediaFile mediaFile : fileList) {
                    if(mediaFile.getChapterId().equals(courseChapter.getId())){
                        mediaFiles.add(mediaFile);
                    }
                }
            });
            map.put("courseChapters",courseChapterList);
        }
        map.put("course",course);
        map.put("courseMarket",courseMarket);

        map.put("courseSummary",courseSummary);
        map.put("courseDetail",courseDetail);
        map.put("teachers",teachers);
        return JsonResult.success().setData(map);
    }




    private void synchronizeDataToES(List<Long> ids) {
        List<Course> CourseList = baseMapper.selectList(new QueryWrapper<Course>().in("id", ids));
        List<CourseDoc> courseDocList = new ArrayList<>();
        //同步到 es里面
        CourseList.forEach(course->{
            //给courseDoc赋值
            setCourseDocData(courseDocList, course);
            //发送消息
            courseMessageProducer.sendMessage(course);
        });
        searchCourseOpenfeign.save(courseDocList);
    }



    private void setCourseDocData(List<CourseDoc> courseDocList, Course course) {
        //主表同步
        CourseDoc courseDoc = new CourseDoc();
        //BeanUtils.copyProperties 作用 就是把 对应类型的属性名相同的进行复制
        BeanUtils.copyProperties(course,courseDoc);
        //courseTypeName
        CourseType type = courseTypeMapper.selectOne(new QueryWrapper<CourseType>().eq("id", course.getCourseTypeId()));
        courseDoc.setCourseTypeName(type.getName());
        //startTime
        courseDoc.setStartTime(course.getStartTime().getTime());
        //endTime
        courseDoc.setEndTime(course.getEndTime().getTime());
        //onlineTime
        courseDoc.setOnlineTime(course.getOnlineTime().getTime());
        //详情表同步 ----------------------------
        CourseDetail courseDetail = courseDetailMapper.selectOne(new QueryWrapper<CourseDetail>().eq("id", course.getId()));
        BeanUtils.copyProperties(courseDetail,courseDoc);
        //课程收费-----------------------------------
        CourseMarket courseMarket= courseMarketMapper.selectOne(new QueryWrapper<CourseMarket>().eq("id", course.getId()));
        BeanUtils.copyProperties(courseMarket,courseDoc);
        //课程销售情况
        CourseSummary courseSummary = courseSummaryMapper.selectOne(new QueryWrapper<CourseSummary>().eq("id", course.getId()));
        if (courseSummary != null){
            BeanUtils.copyProperties(courseSummary,courseDoc);
        }
        //获取该商品的收藏数
        Integer count = courseCollectMapper.selectCount(new QueryWrapper<CourseCollect>().eq("course_id", course.getId()));
        courseDoc.setCollectCount(count);

        courseDocList.add(courseDoc);
    }


    private JsonResult updateOnLineStatus(List<Long> ids){
        AssertUtil.isFalse(ids.isEmpty(),"老铁，你不选中数据，臣妾上不了啊....");
        //去数据库查询 看是否有已上线的
        QueryWrapper<Course> in = new QueryWrapper<Course>()
                .eq("status", RConst.Num.INT_1)
                .in("id", ids);
        List<Course> courses = baseMapper.selectList(in);//这里如果有数据表示  用户选择已上线的数据
        if(!courses.isEmpty()){
            return JsonResult.error("老铁，你部要选择已上线的数据....");
        }
        //如果前面都没有问题  用户选择没有选择已上线的数据
//        List<Course> list = baseMapper.selectList(new QueryWrapper<Course>()
//                .in("id", ids));//这里如果有数据表示  用户选择已上线的数据
//        list.stream().forEach(course -> {
//            course.setStatus(RConst.Num.INT_1);
//            course.setOnlineTime(new Date());
//        });
        baseMapper.batchUpdate(ids,RConst.Num.INT_1);
        return null;
    }
}
